package com.bds.btcdc.adapter.okex.trade.service;

import com.alibaba.fastjson.JSONObject;
import com.bds.btcdc.adapter.okex.trade.OkexAPIClient;
import com.bds.btcdc.adapter.service.ITradeService;
import com.bds.btcdc.adapter.zb.ZBAPIClient;
import com.bds.btcdc.api.model.*;
import com.bds.btcdc.model.UserKeys;
import com.bds.btcdc.service.UserKeysService;
import com.bds.btcdc.util.Const;
import com.bds.btcdc.util.EhcacheUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.text.DecimalFormat;

/**
 * Created by DongChenchen on 2018/5/9 0008
 * zb交易api
 */
@Service
public class OkexTradeService implements ITradeService{
    private static final Logger logger = LoggerFactory.getLogger(OkexTradeService.class);
    private DecimalFormat df = new DecimalFormat(Const.END_WITH_COUNT);
    @Autowired
    private UserKeysService userKeysService;
    /**
     * 获取资产情况
     */
    @Override
    public Result getAccount(UserKeys keys) {
        Result res=new Result();
        logger.info("获取okex资产情况。。。。。。。。。。。。。。");
        OkexAPIClient client = OkexAPIClient.getInstance(keys.getUser_id(),keys.getAccess_key(),keys.getSecret_key());
        String resu = client.getAccountInfo();
        if(!StringUtils.isEmpty(resu)) {
            JSONObject jsonObj = JSONObject.parseObject(resu);
                try {
                    JSONObject infoObj =jsonObj.getJSONObject("info");
                    JSONObject funds = infoObj.getJSONObject("funds");
                    JSONObject free = funds.getJSONObject("free");
                    JSONObject freezed = funds.getJSONObject("freezed");
                    Map<String,List<String>>assets=new HashMap<>();
                    for(String coin:free.keySet()){
                        List<String> money=new ArrayList<>();
                            money.add(free.getString(coin));
                        assets.put(coin,money);
                    }
                    for(String coin:freezed.keySet()){
                        List<String> money=null;
                        if(assets.containsKey(coin)){
                            money=assets.get(coin);
                            money.add(freezed.getString(coin));
                        }else{
                            money=new ArrayList<>();
                            money.add(free.getString(coin));
                        }
                        assets.put(coin,money);
                    }
                    AccountInfo info = new AccountInfo();
                        info.setUserId(keys.getUser_id());
                        info.setExchange(Const.OKEX.EXCHANGE);
                    List<Asset> info_coins = new ArrayList<>();
                    for(Map.Entry<String,List<String>> ass:assets.entrySet()) {
                        try {
                            Asset asset = new Asset();
                            String currency = ass.getKey();
                            asset.setCurrency(currency);
                            String num = ass.getValue().get(0);
                            asset.setCount(df.format(Double.valueOf(num)));
                            if (ass.getValue().size() > 1) {
                                asset.setFreez_count(df.format(Double.valueOf(ass.getValue().get(1))));
                            } else {
                                asset.setFreez_count(df.format(0.0));
                            }
                            //只返回不为0 的币种
                            if (BigDecimal.ZERO.compareTo(new BigDecimal(asset.getCount())) != 0
                                    || BigDecimal.ZERO.compareTo(new BigDecimal(asset.getFreez_count())) != 0) {//过滤掉 为0的币种
                                if (!"USDT".equals(currency.toUpperCase()) && !"USD".equals(currency.toUpperCase())) {
                                    //从缓存中取出 usdt币对的最新交易价格
                                    String keys1 = Const.OKEX.EXCHANGE + "#" + currency.toUpperCase() + "_USDT";
                                    String keys2 = Const.OKEX.EXCHANGE + "#" + currency.toUpperCase() + "_USD";
                                    String last_price1 = EhcacheUtils.getInstance().getCache(keys1);
                                    String last_price2 = EhcacheUtils.getInstance().getCache(keys2);
                                    String last_price = StringUtils.isEmpty(last_price1) == true ? last_price2 : last_price1;
                                    if (!StringUtils.isEmpty(last_price)) {
                                        asset.setLast_price(df.format(Double.valueOf(last_price)));
                                    } else {
                                        String last= OkexAPIClient.getInstatnce().getPriceBySymbol(currency.toLowerCase() + "_usdt");
                                        BigDecimal lastPrice = new BigDecimal(last);
                                        asset.setLast_price(df.format(lastPrice));
                                    }
                                } else if ("USDT".equals(currency.toUpperCase()) || "USD".equals(currency.toUpperCase())) {
                                    asset.setLast_price(df.format(1));//最新成交价(以usdt为单位)
                                }
                                //设置可用金额，冻结金额
                                if(asset.getCount()!=null&&asset.getLast_price()!=null){
                                    BigDecimal amount=new BigDecimal(asset.getLast_price()).multiply(new BigDecimal(asset.getCount()));
                                    asset.setAmount(df.format(amount));
                                }
                                if(asset.getFreez_count()!=null){
                                    BigDecimal freez=new BigDecimal(asset.getLast_price()).multiply(new BigDecimal(asset.getFreez_count()));
                                    asset.setFreez(df.format(freez));
                                }
                                info_coins.add(asset);
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                            continue;
                        }
                    }
                    info.setAssetList(info_coins);
                    res.setResult(Const.SUC,info);
                    return res;
                }catch (Exception e){
                    e.printStackTrace();
                    res.setResult(Const.FAIL,"从zb获取资产数据无效");
                }
        }else{
            res.setResult(Const.FAIL,"连接zb异常,未返回数据！");
        }
        return null;
    }



    /**
     * 参数校验，都不能为空
     *
     * @return
     */
    private boolean volidate(Map<String, String> args) {
        for (Map.Entry<String, String> entry : args.entrySet()) {
            if (StringUtils.isEmpty(entry.getValue())) {
                return false;
            }
        }
        return true;
    }

    @Override
    public Result makeOrder(Order order) {
        long user_id=order.getUserId();
        UserKeys keys=userKeysService.getByUserIdAndExchange(user_id,Const.OKEX.EXCHANGE);
        OkexAPIClient client=OkexAPIClient.getInstance(user_id,keys.getAccess_key(),keys.getSecret_key());
        String json = client.makeOrder(order.getSymbol(), order.getType(), order.getPrice(), order.getNum());
        logger.info("okex 下单 >>> "+json);
        Result rst=new Result();
        if(json==null){
            rst.setResult(Const.FAIL,"okex-api服务异常");
            return rst;
        }else {
            JSONObject obj=JSONObject.parseObject(json);
            String result=obj.getString("result");
            if("true".equals(result)){
                String order_id=obj.getString("order_id");
                OrderResponse response=new OrderResponse();
                response.setStatus("ok");
                response.setOrder_id(order_id);
                rst.setResult(Const.SUC,response);
                return rst;
            }else{
                rst.setResult(Const.FAIL,"okex-api 请求返回失败");
                return rst;
            }
        }
    }

    @Override
    public Result cancelOrder(long userId, String orderId) {
        return null;
    }

    @Override
    public Result getOrder(long userId, String orderId) {
        return null;
    }

}
